Home |
| Latest | About | Random
# Laundry list (In-progress) **This shows you an example of how you can make a laundry list for yourself.** This is just what comes to my head. I make no guarantee this is complete nor comprehensive. It is updated continuously with details edited. Let me know if I missed something. By the way, it is a good exercise to make such a laundry list yourself for review! And of course, this isn't enough to "master" C++, you should read and write code as well! ## Preliminaries. - Basic C++ skeleton program `int main() { return 0; }` - Semicolon `;` to end a statement. - `#include ` allows `std::cout` to print to the screen. - `using namespace std;` allows us to not write `std::` all the time. - Using the stream insertion operator `<<` to "flow" things into `cout` to print. - `cout << "hi " << "mom" << endl;` - Escape sequences `\n`, `\\`, `\"` - A `"string literal"` enclosed in double-quotes. ## Declaring, defining, and assigning to variables. - To declare a variable with identifier (name) `x` and type `T` we write `T x;` - Here the type `T` could be `int`, `double`, `char`, `bool`, `string`, `size_t`, `unsigned int` that we have seen so far. - For example `int x;` to declare a variable with identifier `x` of type `int`. - Use a memory box model to help keep track of your variable. - To assign to a declared variable `x` the value `value` we write `x = value;` - Cannot use a variable that has not been declared. This is a build error. - We can also initialize a variable with a value at the moment of declaration by `T x = value;` - If we have `x = expr` where `expr` is some expression, then the expression is first evaluated, then assigned to the variable `x`. ## Fundamental type `int`. - `int` type is generally for integers, both positive and negative. But `int` has a limit to what integers it can hold. - On most modern machines it is between $-2^{31}$ to $2^{31}-1$ inclusively, or `-2147483648` to `2147483647`, or negative two billion-ish to two billion-ish. - Going beyond these limits of `int` gives undefined behavior. In practice it usually wraps around silently, but you cannot rely on that. - A declared but unassigned `int` variable like `int x;` holds junk value. Using it without assignment leads to undefined behavior. - Operations among `int`s: `+`, `-`, `*`, `/`, `%`, `++`, `--`, `+=`, `-=`, `*=`, `/=`, `%=`, `(` and `)`. - `++x` is pre-increment: It first adds `1` to the current value of `x`, updates it, then returns `x`. - `x++` is post-increment: It first returns a copy of the value of `x`, then updates `x` by adding `1` to it. - If `a` and `b` are both `int`s, then `a / b` is integer division and you get the quotient, or truncation of the decimal parts. - For `a % b` you get the remainder, and it matches the sign of `a`. - Division or modulo operation by `0` gives undefined behavior. - `+=` is compound assignment, doing `x += a;` amounts to doing `x = x + a;` Similarly with `*=`, `-=`, `/=`, and `%=`. ## Fundamental type `double`. - `double` type is generally for numbers with decimal parts. Any number with a decimal point `.` is a double. - But `double` is limited to (1) which decimal number it can actually represent, and (2) what range it can hold. - `double` has limited precision of about 15-17 significant figures. It can try to represent numbers with magnitude of about `1e-308` to `1e308`, both positive and negative, but it is not precise. - Famously a `double` cannot store `20.15` exactly. - A declared but unassigned `double` variable like `double x;` holds junk value. Using it without assignment leads to undefined behavior. - Operations among `double`s: `+`, `-`, `*`, `/`, `+=`, `-=`, `*=`, `/=`, `++`, `--`, `(` and `)`. - Division, if not by `0`, gives decimal (approximation) of the division. The result is a `double`. - `%` does not work with `double`, it will give build error. - Using the stream manipulator `std::setprecision(n)` from the header `` we can set the number of digits shown for `double`. For example if we have `double x = 3.14159`, then `cout << setprecision(4) << x` will display `3.142`. The effect of `setprecision` remains for all future `cout`. - The function `round(d)` will take a `double d` and round it to the nearest integer as a `double`, where a half will round away from `0`. - `round(3.99)` will give you `4.0` - `round(3.5)` will give you `4.0` - `round(-1.5)` will give you `-2.0` - `round(-1.2)` will give you `-1.0` ## Implicit casting between `int` and `double`. - "casting" means converting from one type to another. - Assign to an `int` variable with a `double` value like `int x = 3.99;` we get truncation. The value of `x` is the `int` `3`. - Assign to a `double` variable with an `int` value like `double x = 3;` we just get the `double` version of the integer. So `x` holds the `double` `3.0`. - Recall with assignment `x = expr` the expression on the right is evaluated first. So `double x = 5 / 2;` we get `x` having the double `2.0`, as `5 / 2` is an `int` division that gives `2`. - Among the binary operations `a + b`, `a - b`, `a * b`, `a / b`, if one of them is a `double` and the other is an `int`, then the `int` is converted to a `double`, and gives a result in `double`. - `double x = 5.0 / 2;` will result in `x` having the value `2.5`. - We can explicitly cast an `int x` into a `double` by doing `static_cast(x)`. This does not change `x`, but rather we get a new `double` that is `static_cast(x)` itself. - We can explicitly cast a `double x` into an `int` by doing `static_cast(x)`. This does not change `x`, but we get an `int` by truncating `x`, given by `static_cast(x)`. ## Fundamental type `bool`. - A `bool` takes on two possible values, `true` or `false`. You get them by asking yes or no questions. - By default, `std::cout` prints `true` to `1` and `false` to `0`. - One can feed `cout` with `boolalpha` or `noboolalpha` to toggle between printing `true` or `false` and `1` or `0`. - Operators like comparison `==`, `<`, `>=`, `>`, `>=`, `!=` can get `bool`s. - One can also use logical operators `&&`, `||`, and `!` to get new `bool`s from `bool`s. ## Logical operators `&&`, `||`, and `!`. - If `a` and `b` are `bool`s... - `a && b` is true if and only if both `a` and `b` are true - `a || b` is true if and only if at least one of `a` or `b` is true - `!a` is true if and only if `a` is false - They are useful to also shorten `if-else` statements! ## Fundamental type `char`. - The `char` data type stores a single character, enclosed in single-quote, like `'a'`, `'G'`, `'!'`, `'\n'`, `' '`, `'3'`. - Each `char` is secretly a small number, the character code of the character given by the ASCII table. - The upper case characters `'A'`, `'B'`, ..., `'Z'` have character codes that increase in order. It just so happens that `'A'` has character code 65. - The lower case characters `'a'`, `'b'`, ..., `'z'` have character codes that increase in order. It just so happens that `'a'` has character code 97. - The digit characters `'0'`, `'1'`, ..., `'9'` have character codes that increase in order. It just so happens that `'0'` has character code 48. - When an `int` is implicitly casted as a `char`, then we get the `char` that has that character code. - `char ch = 100;`, then here `ch` holds the character `'d'`. - When a `char` is implicit casted as an `int`, then we get the character code of that `char` - `int i = 'd';`, then here `i` holds the integer `100`. - Arithmetic with `char` are done with their character codes. - `int x = 'd' - 'b';`, here `x` holds the `int` `2`. - `int y = ('j' - 'c') / 2;`, here `y` holds the `int` `3`. - `char ch = 'd' + 5;`, here `ch` holds the `char` `'i'`. - When `'d' + 5` is performed, the result is an `int`. But when we then assign it to `char ch`, it gets casted into a `char`. - Useful arithmetic patterns involving `char`: - `'A' - 'a'` or `'a' - 'A'`. - `char ch = 'b' + 'A' - 'a';` gives `ch` as the `char` `'B'`. - `ch - '0'`, where `ch` is a `char` from `'0'` to `'9'`. - `char ch = '7'; int x = ch - '0';` gives `x` the `int` `7`. - `i + '0'`, where `i` is an `int` from `0` to `9`. - `int i = 5; char ch = i + '0';` gives `ch` the `char` `'5'`. ## Fundamental type `unsigned int`. - Unsigned means no negatives. An `unsigned int` can hold an integer between `0` to about 4 billion-ish (on most machines). - Overflow behavior is designed to wrap around. This is expected behavior and not an error. ## Fundamental type `size_t`. - Also an unsigned type. But a `size_t` can hold an integer between `0` to about 18 quintillion (on most machines), which is huge! - Also have same overflow behavior that wraps around. This is not an error. - `size_t` is useful in describing index of things or sizes of things. - The upper limit `static_cast(-1)`, or `string::npos`, is often used as a **sentinel value** to indicate something. - As `size_t` wraps around, `-1` casted in `size_t` actually is this huge 18 quintillion number, which realistically can never be reached if one counts from `0` up to it. Nor can sizes be that big. - So it is useful if the return type of a function is `size_t` but you want to indicate some kind of out of place behavior has been encountered. - Like in `string`, say we have `string s = "apple"` and we try to do `s.find('p')`. This correctly gives `1` as that is the index of the first instance of the character `p` in `s`. However, if we do `s.find('x')`, we will get the value `static_cast(-1)`, namely huge number. This is because it cannot find it, but it has to give a `size_t` somehow. ## `const` keyword. - If a variable has `const` in front when initialized, then it becomes read only. Like `const int x = 3;` You must initialize a `const` with a value, for example `const int x;` gives a build error, unless it has a default value like `string` (the default being empty string). - Use `const` variable when you think something will not be modified, and/or should not get modified later. - This can help us avoid using magic numbers. ## `string` class. - The `string` data type stores text. - Member functions of a `string s` - `s.length()` - `s.at(i)` - `s.substr(t)` - `s.substr(t,i)` - `s.find(t)` - `s.find(t,i)` - `s.rfind(t)` - `s.rfind(t,i)` ## `cin >> x`. A summary of doing `cin >> x` - If `cin` not in fail state and the input buffer is empty, allow the user to type. - `ENTER` key is `\n` character. - If the input buffer is not empty: - Remove all leading whitespaces, and check if input buffer is empty again. - Read as many characters in the input buffer **except whitespaces** as the same type as `x`. Extracts them from the input buffer and store it in `x`. - If extracted nothing then put `cin` in fail state. - Note, `cin >> x >> y >> z;` is the same as separate `cin >> x; cin >> y; cin >> z`. ## Dealing with input buffer. - Often it might be simpler to imagine the user has typed all there is to be typed into the input buffer. So you can start there as the starting point of what the input buffer holds. - For example, if the user is to type `Hello darkness my old friend`, then `ENTER` key, followed by `I've come to talk with you again`, then `ENTER` key. Then you can imagine the input buffer has the following: ``` Hello darkness my old friend\n I've come to talk with you again\n ``` - Then you can look at your code with the functions that deal with the input buffer and see how the characters are consumed from the buffer. ## `getline`. A summary of doing `getline(cin, x)`, where `x` is a `string`. - If `cin` not in fail state and the input buffer is empty, allow the user to type. - `ENTER` key is `\n` character. - If the input buffer is not empty: - Read as many characters in the input buffer just before the first `\n` character it sees. Extract those characters and store into `string x`. This can be empty string. - Next, remove the `\n` character earlier in the input buffer. ## `cin.ignore()`. A summary of doing `cin.ignore()`. - If `cin` not in fail state and the input buffer is empty, allow the user to type. - `ENTER` key is `\n` character. - If the input buffer is not empty: - Removes the first character in the input buffer. ## `cin.get()`. A summary of doing `x = cin.get()`, where `x` is a `char`. - If `cin` not in fail state and the input buffer is empty, allow the user to type. - `ENTER` key is `\n` character. - If the input buffer is not empty: - Extracts the first character from the input buffer, and stores it in `char x`. ## `cin.peek()`. A summary of doing `cin.ignore()`. - If `cin` not in fail state and the input buffer is empty, allow the user to type. - `ENTER` key is `\n` character. - If the input buffer is not empty: - Copies the first character from the input buffer, and stores it in `char x`. Leaving input buffer untouched. ## Control flow `if`, `else`, `else if`. ## Scope with `{` and `}`. ## Control flow `while`. ## Control flow `for`. ## `` header. The `` header contains some useful functions that you've encountered in class or homework: - `round(x)` - `pow(x,p)` - `sqrt(x)` ## `` header. The `` header contains some useful functions that you've encountered in class or in homework: - `min` - `max` ## `` header. The `` header contains some useful functions that you've encountered in class or in homework: - `swap`